package com.ufcg.lvc.client.prototipacao;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TextBox;
import com.ufcg.lvc.client.GreetingServiceCRUD;
import com.ufcg.lvc.client.GreetingServiceCRUDAsync;
import com.ufcg.lvc.client.UserData;

public class NovaTurma {

	private AbsolutePanel painelNovaTurma;
	private TextBox nome;
	private ListBox alunos,ano;
	private SuggestBox disciplina,instituicao;
	private ArrayList<String> alunosAdd = new ArrayList<String>();
	private TextBox tbDisciplina,tbInstituicao;
	private boolean editar = false;
	private boolean exibir = false;
	private SuggestBox novoAluno;
	private Label lblNomeTurma, lblTitulo,lblDisciplina,lblInstituicao,lblListaAlunos,lblAno,lblNovoAluno;
	private Button btnAddAluno,btnRemoverAluno,btnCancelar;
	private String instituicaoAntiga,disciplinaAntiga,nomeAntigo;
	private List<String> alunosCadastrados,turmasCadastradas;
	UserData UD;
	
	public static GreetingServiceCRUDAsync getServicoCRUD() {
		return GWT.create(GreetingServiceCRUD.class);
	}

	public NovaTurma(UserData uD) {
		UD = uD;
		editar = false;
		init();
		draw();
	}
	
	/** Editar questao/exibir*/
	public NovaTurma(String nome, String disciplina, String instituicao, String ano, boolean editar,UserData uD) {
		UD = uD;
		nomeAntigo = nome;
		if (editar == true){
			this.editar = true;
			this.exibir = false;
		}else {
			this.editar = false;
			this.exibir = true;
		}
		init();
		try {
			draw();	
		} catch (Exception e) {
		}
		atualizarCampos(nome, disciplina, instituicao, ano);
	}

	private void atualizarCampos(String nome2, String disciplina2, String instituicao2,	String ano2) {
		getServicoCRUD().getAlunosDaTurma(nomeAntigo, UD.getId_usuario(), new AsyncCallback<List<String>>() {
			@Override
			public void onSuccess(List<String> result) {
				for (String umAluno : result) {
					alunos.addItem(umAluno);	
					alunosAdd.add(umAluno);
				}
			}
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro na comunicação com o servidor");
			}
		});
		this.nome.setText(nome2);
		instituicaoAntiga = instituicao2;
		disciplinaAntiga = disciplina2;
		this.tbInstituicao.setText(instituicao2);
		this.tbDisciplina.setText(disciplina2);
		
		int i = 0;
		while (!ano.getItemText(i).equals(ano2)) {
			i++;			
		}
		this.ano.setSelectedIndex(i);
		
		if (exibir == true){
			this.nome.setEnabled(false);
			this.tbDisciplina.setEnabled(false);
			this.ano.setEnabled(false);
			this.tbInstituicao.setEnabled(false);
		}
	}

	public void draw() {
		
		getServicoCRUD().getTurmas(UD.getId_usuario(), new AsyncCallback<List<List<String>>>() {
			
			@Override
			public void onSuccess(List<List<String>> result) {
				turmasCadastradas = result.get(0);
				if (editar = true){
					turmasCadastradas.remove(nomeAntigo);
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				turmasCadastradas = new ArrayList<String>();
			}
		});
		
		getServicoCRUD().getNomeAlunos(UD.getId_usuario(), new AsyncCallback<List<String>>() {
			@Override
			public void onSuccess(List<String> result) {
				alunosCadastrados = result;
			}
			@Override
			public void onFailure(Throwable caught) {
				alunosCadastrados = new ArrayList<String>();
			}
		});
		
		final AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro na comunicação com o servidor");
			}
			@Override
			public void onSuccess(Boolean result) {
			}
		};
		final AsyncCallback<List<String>> callbackInst = new AsyncCallback<List<String>>() {
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro na comunicação com o servidor");
			}
			@SuppressWarnings("deprecation")
			@Override
			public void onSuccess(List<String> result) {
				MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
		        for (int i = 0; i < result.size(); i++) {
					oracle.add(result.get(i).toString());
				}   
		        instituicao = new SuggestBox(oracle);
		        instituicao.setAnimationEnabled(true);
		        instituicao.setText(instituicaoAntiga);
		        instituicao.setVisible(true);
		        instituicao.setSize("422px", "14px");
		        painelNovaTurma.add(instituicao, 158, 109);
			}
		};
		
		final AsyncCallback<List<String>> callbackDisc = new AsyncCallback<List<String>>() {
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro na comunicação com o servidor");
			}

			@SuppressWarnings("deprecation")
			@Override
			public void onSuccess(List<String> result) {
				MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
		        for (int i = 0; i < result.size(); i++) {
					oracle.add(result.get(i).toString());
				}
		        
		        disciplina = new SuggestBox(oracle);
		        disciplina.setAnimationEnabled(true);
		        disciplina.setVisible(true);
		        disciplina.setText(disciplinaAntiga);
		        disciplina.setSize("422px", "14px");
		        painelNovaTurma.add(disciplina, 158, 153);
			}
		};
		
		final AsyncCallback<List<String>> callbackAlunos = new AsyncCallback<List<String>>() {
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro na comunicação com o servidor");
			}

			@SuppressWarnings("deprecation")
			@Override
			public void onSuccess(List<String> result) {
				MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
		        for (int i = 0; i < result.size(); i++) {
					oracle.add(result.get(i).toString());
				}
		        novoAluno = new SuggestBox(oracle);
				novoAluno.setSize("463px", "14px");
				novoAluno.setAnimationEnabled(true);
				novoAluno.setVisible(true);
				painelNovaTurma.add(novoAluno, 240, 404);
		       	}
		};
		
		painelNovaTurma.setSize("900px", "707px");
		
		
		if (exibir == false){
			getServicoCRUD().getNomeIntituicoes(UD.getId_usuario(), callbackInst);
			getServicoCRUD().getNomeDisciplinas(callbackDisc);
			getServicoCRUD().getNomeAlunos(UD.getId_usuario(), callbackAlunos);
		}else {
		    tbDisciplina.setSize("422px", "14px");
	        painelNovaTurma.add(tbDisciplina, 158, 153);
	        tbInstituicao.setSize("422px", "14px");
	        painelNovaTurma.add(tbInstituicao, 158, 109);    
		}
		
		if (exibir == true){
			lblTitulo.setText("Turma");
		} else if (editar == true){
			lblTitulo.setText("Editar turma");
		}
		lblTitulo.setStyleName("gwt-TituloMedio");
		painelNovaTurma.add(lblTitulo, 0, 10);
		
		painelNovaTurma.add(lblNovoAluno, 158, 404);
		painelNovaTurma.add(lblNomeTurma, 60, 69);
		lblNomeTurma.setSize("43px", "17px");

		painelNovaTurma.add(lblInstituicao, 60, 109);
		lblInstituicao.setSize("165px", "17px");

		lblDisciplina.setDirectionEstimator(true);
		painelNovaTurma.add(lblDisciplina, 60, 153);
		lblDisciplina.setSize("75px", "17px");
		
		painelNovaTurma.add(lblNovoAluno, 158, 404);
		painelNovaTurma.add(lblListaAlunos, 60, 245);
		lblListaAlunos.setSize("80px", "17px");

		painelNovaTurma.add(lblAno, 60, 194);
		lblAno.setSize("61px", "17px");

		painelNovaTurma.add(nome, 158, 69);
		nome.setSize("422px", "14px");

		if (exibir == true){
			btnCancelar.setText("Voltar");
			painelNovaTurma.add(btnCancelar, 409, 461);
		}else {
			painelNovaTurma.add(btnCancelar, 449, 461);
		}
		
		btnCancelar.setSize("81px", "30px");
		
		ano.addItem("2012");
		ano.addItem("2013");
		ano.addItem("2014");
		ano.addItem("2015");
		ano.addItem("2016");
		ano.addItem("2017");
		ano.addItem("2018");
		ano.addItem("2019");
		ano.addItem("2020");
		ano.addItem("2021");
		ano.addItem("2022");
		ano.addItem("2023");
		ano.addItem("2024");
		ano.addItem("2025");
		
		painelNovaTurma.add(ano, 158, 194);
		
		alunos.setSize("553px", "153px");
		alunos.setVisibleItemCount(5);
		painelNovaTurma.add(alunos, 158, 245);

		
		if (exibir == false){
			painelNovaTurma.add(btnAddAluno, 714, 401);
			btnAddAluno.setSize("81px", "30px");
			
			painelNovaTurma.add(btnRemoverAluno, 714, 245);
			btnRemoverAluno.setSize("81px", "30px");
			
			btnAddAluno.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					String result = verificarAlunoNaLista(novoAluno.getText());
					if (result.equals("") && !novoAluno.getText().trim().equals("")) {
						alunos.addItem(novoAluno.getText());
						alunosAdd.add(novoAluno.getText());
						novoAluno.setText("");
					} else {
						com.google.gwt.user.client.Window.alert(result);
					}
				}				
			});
			
			btnRemoverAluno.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					if (alunos.getSelectedIndex() != -1 && verificarRemocao(alunos.getItemText(alunos.getSelectedIndex()))) {
						for (int i = 0; i < alunosAdd.size(); i++) {
							if (alunosAdd.get(i).equals(alunos.getItemText(alunos.getSelectedIndex()))){
								alunosAdd.remove(i);
							}
						}alunos.removeItem(alunos.getSelectedIndex());
					} else {
						com.google.gwt.user.client.Window.alert("Selecione o aluno que deseja remover.");
					}
				}
			});
		}
		
		btnCancelar.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				voltar();
			}

		});
		
		if (exibir == false){
			final Button btnSalvar = new Button("Salvar");
			painelNovaTurma.add(btnSalvar, 362, 461);
			btnSalvar.setSize("81px", "30px");
			btnSalvar.addClickHandler(new ClickHandler() {	
				public void onClick(ClickEvent event) {
					
					if (!nome.getText().trim().equals("") && !instituicao.getText().trim().equals("") && !disciplina.getText().trim().equals("")) {
						if (!turmasCadastradas.contains(nome.getText())){
							if (alunos.getItemCount()>=1){
								if (editar == true){
									getServicoCRUD().updateTurma(nomeAntigo, nome.getText(), instituicao.getText(), disciplina.getText(), ano.getItemText(ano.getSelectedIndex()), alunosAdd, UD.getId_usuario(), callback);
								}else{
									getServicoCRUD().salvarTurma(instituicao.getText(), disciplina.getText(), nome.getText(), ano.getItemText(ano.getSelectedIndex()), alunosAdd, UD.getId_usuario(), callback);
								}voltar();
							} else {
								com.google.gwt.user.client.Window.alert("A turma deve possuir pelo menos um aluno.");
							}
						} else {
							com.google.gwt.user.client.Window.alert("Nome não disponível. Já existe uma turma com este nome.");
						}
					}
					else {
						com.google.gwt.user.client.Window.alert("Todos os campos devem ser preenchidos.");
					}
					
				}
			});
		}
	}

	
	public void init() {
    	tbDisciplina = new TextBox();			
    	tbInstituicao = new TextBox();
	
		disciplina = new SuggestBox();
		instituicao = new SuggestBox();
    	novoAluno = new SuggestBox();
    	btnRemoverAluno = new Button("Excluir");
		btnAddAluno = new Button("Adicionar");
	
		painelNovaTurma = new AbsolutePanel();
		lblTitulo = new Label("Nova turma");
		
		lblNomeTurma = new Label("Nome:");
		lblInstituicao = new Label("Instituição:");
		lblDisciplina = new Label("Disciplina:");
		lblListaAlunos = new Label("Alunos:");
		lblAno = new Label("Ano:");
		lblNovoAluno = new Label("Novo aluno:");
		
		nome = new TextBox();
		btnCancelar = new Button("Cancelar");
			
		ano = new ListBox();
		alunos = new ListBox();
	}
	
	public AbsolutePanel getPanel() {
		return painelNovaTurma;
	}
	private void voltar() {
		painelNovaTurma.clear();
		final MinhasTurmas n = new MinhasTurmas(UD);
		painelNovaTurma.add(n.getPanel());
	}
	
	private String verificarAlunoNaLista(String novoAluno) {
		for (String a : alunosAdd) {
			if(a.equals(novoAluno)){
				return "Aluno já adicionado.";
			}
		}		
		for (String aluno : alunosCadastrados) {
			if (aluno.equals(novoAluno)){
				return ""; // pode adicionar
			}
		}
		return "Aluno não encontrado. Apenas alunos cadastrados podem ser adicionados.";
	}
	
	private Boolean verificarRemocao(String novoAluno) {
		for (String a : alunosAdd) {
			if(a.equals(novoAluno)){
				return true;
			}
		}	
		return false;
	}
}
